import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
    View,
    Text,
    TouchableOpacity,
    StyleSheet,
    Platform,
    Animated,
    ActivityIndicator,
    Vibration,
} from 'react-native';
import { theme } from '../../styles/theme';

// 音频录制器接口
export interface AudioRecorderInterface {
    start: () => Promise<void>;
    pause: () => void;
    resume: () => void;
    stop: () => Promise<Blob>;
    getDuration: () => number;
    isRecording: () => boolean;
    isPaused: () => boolean;
    release: () => void;
}

// Web平台录音实现
export class WebAudioRecorder implements AudioRecorderInterface {
    private mediaRecorder: MediaRecorder | null = null;
    private chunks: Blob[] = [];
    private stream: MediaStream | null = null;
    private startTime: number = 0;
    private pausedTime: number = 0;
    private duration: number = 0;
    private paused: boolean = false;
    private recording: boolean = false;
    private timer: NodeJS.Timeout | null = null;
    private onDurationChange: ((duration: number) => void) | null = null;
    private onAmplitudeChange: ((amplitude: number) => void) | null = null;
    private audioContext: AudioContext | null = null;
    private analyzer: AnalyserNode | null = null;

    constructor() {
        // Set up defaults
    }

    public setOnDurationChange(callback: (duration: number) => void): void {
        this.onDurationChange = callback;
    }

    public setOnAmplitudeChange(callback: (amplitude: number) => void): void {
        this.onAmplitudeChange = callback;
    }

    public async start(): Promise<void> {
        if (this.recording) {
            return; // Already recording
        }

        // Reset state
        this.chunks = [];
        this.startTime = Date.now();
        this.pausedTime = 0;
        this.duration = 0;
        this.paused = false;
        this.recording = true;

        try {
            // 请求麦克风权限
            this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });

            // 设置音频分析器
            if (this.onAmplitudeChange) {
                this.setupAudioAnalyzer();
            }

            // 创建MediaRecorder
            this.mediaRecorder = new MediaRecorder(this.stream);

            // 设置事件处理
            this.mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) {
                    this.chunks.push(event.data);
                }
            };

            // 开始录制
            this.mediaRecorder.start(100); // 每100ms触发一次ondataavailable事件
            this.startDurationTimer();

        } catch (error) {
            console.error('Failed to start recording:', error);
            this.recording = false;
            throw new Error('无法访问麦克风，请确保已授予权限');
        }
    }

    public pause(): void {
        if (!this.recording || this.paused || !this.mediaRecorder) {
            return;
        }

        this.paused = true;
        this.pausedTime = Date.now();
        this.mediaRecorder.pause();
        this.stopDurationTimer();
    }

    public resume(): void {
        if (!this.recording || !this.paused || !this.mediaRecorder) {
            return;
        }

        this.paused = false;
        if (this.pausedTime > 0) {
            const pauseDuration = Date.now() - this.pausedTime;
            this.startTime += pauseDuration;
            this.pausedTime = 0;
        }
        this.mediaRecorder.resume();
        this.startDurationTimer();
    }

    public async stop(): Promise<Blob> {
        return new Promise((resolve, reject) => {
            if (!this.recording || !this.mediaRecorder) {
                reject(new Error('没有正在进行的录音'));
                return;
            }

            // 设置录音结束处理
            this.mediaRecorder.onstop = () => {
                const blob = new Blob(this.chunks, { type: 'audio/wav' });
                this.release();
                resolve(blob);
            };

            // 停止录音
            this.mediaRecorder.stop();
            this.stopDurationTimer();
            this.recording = false;
            this.paused = false;
        });
    }

    public getDuration(): number {
        if (!this.recording) {
            return this.duration;
        }

        if (this.paused) {
            return (this.pausedTime - this.startTime) / 1000;
        }

        return (Date.now() - this.startTime) / 1000;
    }

    public isRecording(): boolean {
        return this.recording && !this.paused;
    }

    public isPaused(): boolean {
        return this.recording && this.paused;
    }

    public release(): void {
        this.stopDurationTimer();

        if (this.mediaRecorder) {
            if (this.mediaRecorder.state !== 'inactive') {
                try {
                    this.mediaRecorder.stop();
                } catch (e) {
                    // 忽略stop时的错误
                }
            }
            this.mediaRecorder = null;
        }

        if (this.stream) {
            this.stream.getTracks().forEach(track => track.stop());
            this.stream = null;
        }

        if (this.analyzer) {
            this.analyzer.disconnect();
            this.analyzer = null;
        }

        if (this.audioContext) {
            if (this.audioContext.state !== 'closed') {
                try {
                    this.audioContext.close();
                } catch (e) {
                    // 忽略close时的错误
                }
            }
            this.audioContext = null;
        }

        this.chunks = [];
        this.recording = false;
        this.paused = false;
    }

    private startDurationTimer(): void {
        this.stopDurationTimer();

        this.timer = setInterval(() => {
            this.duration = this.getDuration();
            if (this.onDurationChange) {
                this.onDurationChange(this.duration);
            }
        }, 100);
    }

    private stopDurationTimer(): void {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        }
    }

    private setupAudioAnalyzer(): void {
        if (!this.stream) return;

        try {
            this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
            const source = this.audioContext.createMediaStreamSource(this.stream);
            this.analyzer = this.audioContext.createAnalyser();
            this.analyzer.fftSize = 256;
            source.connect(this.analyzer);

            const dataArray = new Uint8Array(this.analyzer.frequencyBinCount);

            const checkAmplitude = () => {
                if (!this.analyzer || !this.recording || this.paused) return;

                this.analyzer.getByteFrequencyData(dataArray);

                // 计算平均振幅
                let sum = 0;
                for (let i = 0; i < dataArray.length; i++) {
                    sum += dataArray[i];
                }
                const average = sum / dataArray.length;

                // 将值标准化到0-1范围
                const normalizedValue = average / 255;

                if (this.onAmplitudeChange) {
                    this.onAmplitudeChange(normalizedValue);
                }

                requestAnimationFrame(checkAmplitude);
            };

            requestAnimationFrame(checkAmplitude);

        } catch (e) {
            console.error('无法设置音频分析器:', e);
        }
    }
}

// RN平台的录音实现 - 这里是一个基本的模拟实现，实际需要集成native模块如react-native-audio-recorder-player
export class NativeAudioRecorder implements AudioRecorderInterface {
    private recording: boolean = false;
    private paused: boolean = false;
    private startTime: number = 0;
    private pausedTime: number = 0;
    private timer: NodeJS.Timeout | null = null;
    private duration: number = 0;
    private onDurationChange: ((duration: number) => void) | null = null;
    private onAmplitudeChange: ((amplitude: number) => void) | null = null;
    private recordedData: Blob | null = null;

    constructor() {
        // 这里应该初始化native录音模块
    }

    public setOnDurationChange(callback: (duration: number) => void): void {
        this.onDurationChange = callback;
    }

    public setOnAmplitudeChange(callback: (amplitude: number) => void): void {
        this.onAmplitudeChange = callback;
    }

    public async start(): Promise<void> {
        if (this.recording) {
            return;
        }

        // 重置状态
        this.startTime = Date.now();
        this.pausedTime = 0;
        this.duration = 0;
        this.paused = false;
        this.recording = true;
        this.recordedData = null;

        // TODO: 在这里集成实际的RN录音API
        console.log('开始录音 (Native)');

        // 模拟振幅变化
        this.simulateAmplitudeChanges();

        // 开始计时
        this.startDurationTimer();
    }

    public pause(): void {
        if (!this.recording || this.paused) {
            return;
        }

        this.paused = true;
        this.pausedTime = Date.now();

        // TODO: 调用实际的RN录音暂停API
        console.log('暂停录音 (Native)');

        this.stopDurationTimer();
    }

    public resume(): void {
        if (!this.recording || !this.paused) {
            return;
        }

        this.paused = false;
        if (this.pausedTime > 0) {
            const pauseDuration = Date.now() - this.pausedTime;
            this.startTime += pauseDuration;
            this.pausedTime = 0;
        }

        // TODO: 调用实际的RN录音恢复API
        console.log('恢复录音 (Native)');

        this.startDurationTimer();
        this.simulateAmplitudeChanges();
    }

    public async stop(): Promise<Blob> {
        if (!this.recording) {
            return Promise.reject(new Error('没有正在进行的录音'));
        }

        // TODO: 调用实际的RN录音停止API并获取结果
        console.log('停止录音 (Native)');

        this.stopDurationTimer();
        this.recording = false;
        this.paused = false;

        // 模拟录音结果
        this.recordedData = new Blob([], { type: 'audio/wav' });
        return this.recordedData;
    }

    public getDuration(): number {
        if (!this.recording) {
            return this.duration;
        }

        if (this.paused) {
            return (this.pausedTime - this.startTime) / 1000;
        }

        return (Date.now() - this.startTime) / 1000;
    }

    public isRecording(): boolean {
        return this.recording && !this.paused;
    }

    public isPaused(): boolean {
        return this.recording && this.paused;
    }

    public release(): void {
        this.stopDurationTimer();

        // TODO: 释放RN录音资源

        this.recording = false;
        this.paused = false;
        this.recordedData = null;
    }

    private startDurationTimer(): void {
        this.stopDurationTimer();

        this.timer = setInterval(() => {
            this.duration = this.getDuration();
            if (this.onDurationChange) {
                this.onDurationChange(this.duration);
            }
        }, 100);
    }

    private stopDurationTimer(): void {
        if (this.timer) {
            clearInterval(this.timer);
            this.timer = null;
        }
    }

    private simulateAmplitudeChanges(): void {
        if (!this.recording || this.paused || !this.onAmplitudeChange) return;

        const simulateAmplitude = () => {
            if (!this.recording || this.paused) return;

            // 生成模拟振幅(0-1)
            const randomAmplitude = 0.1 + Math.random() * 0.5;
            this.onAmplitudeChange(randomAmplitude);

            // 每100ms更新一次
            setTimeout(simulateAmplitude, 100);
        };

        simulateAmplitude();
    }
}

// 录音可视化组件
const AudioVisualization: React.FC<{
    amplitude: number;
    recording: boolean;
    style?: any;
}> = ({ amplitude, recording, style }) => {
    const bars = 20; // 显示的条数
    const maxBarHeight = 50; // 最大条高

    return (
        <View style={[styles.visualizationContainer, style]}>
            {Array.from({ length: bars }).map((_, index) => {
                // 基于位置和当前振幅计算每个条的高度
                const heightMultiplier = recording
                    ? (Math.sin((index / bars) * Math.PI) * 0.5 + 0.5) * amplitude * 1.5
                    : 0.05;

                const height = Math.max(4, maxBarHeight * heightMultiplier);

                return (
                    <View
                        key={index}
                        style={[
                            styles.visualizationBar,
                            {
                                height,
                                backgroundColor: recording ? theme.colors.primary.main : theme.colors.gray[300],
                            },
                        ]}
                    />
                );
            })}
        </View>
    );
};

// 录音计时器组件
const RecordingTimer: React.FC<{
    duration: number;
    style?: any;
}> = ({ duration, style }) => {
    // 格式化时间为 mm:ss
    const formatTime = (timeInSeconds: number): string => {
        const minutes = Math.floor(timeInSeconds / 60);
        const seconds = Math.floor(timeInSeconds % 60);
        return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    };

    return (
        <Text style={[styles.timerText, style]}>
            {formatTime(duration)}
        </Text>
    );
};

// 录音组件属性
interface AudioRecorderProps {
    onRecordingComplete?: (blob: Blob) => void;
    onError?: (error: Error) => void;
    maxDuration?: number; // 最大录制时长(秒)
    style?: any;
}

// 录音组件
const AudioRecorder: React.FC<AudioRecorderProps> = ({
    onRecordingComplete,
    onError,
    maxDuration = 300, // 默认最大录制5分钟
    style,
}) => {
    // 创建适合当前平台的录音器
    const createRecorder = useCallback((): AudioRecorderInterface => {
        if (Platform.OS === 'web') {
            return new WebAudioRecorder();
        } else {
            return new NativeAudioRecorder();
        }
    }, []);

    const [recorder] = useState<AudioRecorderInterface>(createRecorder());
    const [recording, setRecording] = useState(false);
    const [paused, setPaused] = useState(false);
    const [duration, setDuration] = useState(0);
    const [amplitude, setAmplitude] = useState(0);
    const [error, setError] = useState<Error | null>(null);
    const [initializing, setInitializing] = useState(false);

    // 录音状态动画
    const recordingAnimation = useRef(new Animated.Value(0)).current;

    // 设置录音器回调
    useEffect(() => {
        if (recorder) {
            if (recorder instanceof WebAudioRecorder || recorder instanceof NativeAudioRecorder) {
                recorder.setOnDurationChange((time) => {
                    setDuration(time);

                    // 检查是否超过最大时长
                    if (maxDuration > 0 && time >= maxDuration) {
                        handleStop();
                    }
                });

                recorder.setOnAmplitudeChange((value) => {
                    setAmplitude(value);
                });
            }
        }

        // 组件卸载时释放资源
        return () => {
            if (recorder) {
                recorder.release();
            }
        };
    }, [recorder, maxDuration]);

    // 录音状态变化时的动画
    useEffect(() => {
        Animated.loop(
            Animated.sequence([
                Animated.timing(recordingAnimation, {
                    toValue: 1,
                    duration: 1000,
                    useNativeDriver: true,
                }),
                Animated.timing(recordingAnimation, {
                    toValue: 0.3,
                    duration: 1000,
                    useNativeDriver: true,
                }),
            ])
        ).start();
    }, [recordingAnimation]);

    // 处理开始录音
    const handleStart = async () => {
        try {
            setError(null);
            setInitializing(true);
            await recorder.start();
            setRecording(true);
            setPaused(false);

            // 触觉反馈
            if (Platform.OS !== 'web') {
                Vibration.vibrate(20);
            }
        } catch (err) {
            setError(err instanceof Error ? err : new Error('开始录音失败'));
            if (onError) {
                onError(err instanceof Error ? err : new Error('开始录音失败'));
            }
        } finally {
            setInitializing(false);
        }
    };

    // 处理暂停录音
    const handlePause = () => {
        if (recorder.isRecording()) {
            recorder.pause();
            setPaused(true);

            // 触觉反馈
            if (Platform.OS !== 'web') {
                Vibration.vibrate(10);
            }
        }
    };

    // 处理恢复录音
    const handleResume = () => {
        if (recorder.isPaused()) {
            recorder.resume();
            setPaused(false);

            // 触觉反馈
            if (Platform.OS !== 'web') {
                Vibration.vibrate(10);
            }
        }
    };

    // 处理停止录音
    const handleStop = async () => {
        if (recording) {
            try {
                const blob = await recorder.stop();
                setRecording(false);
                setPaused(false);

                // 触觉反馈
                if (Platform.OS !== 'web') {
                    Vibration.vibrate([0, 30, 50, 30]);
                }

                if (onRecordingComplete) {
                    onRecordingComplete(blob);
                }
            } catch (err) {
                setError(err instanceof Error ? err : new Error('停止录音失败'));
                if (onError) {
                    onError(err instanceof Error ? err : new Error('停止录音失败'));
                }
            }
        }
    };

    // 计算倒计时
    const remainingTime = Math.max(0, maxDuration - duration);
    const remainingPercent = (remainingTime / maxDuration) * 100;

    return (
        <View style={[styles.container, style]}>

            {/* 录音状态指示器 */}
            <View style={styles.statusContainer}>
                {recording && (
                    <View style={styles.statusIndicatorContainer}>
                        <Animated.View
                            style={[
                                styles.recordingIndicator,
                                { opacity: recordingAnimation },
                            ]}
                        />
                        <Text style={styles.statusText}>
                            {paused ? '已暂停' : '录音中...'}
                        </Text>
                    </View>
                )}

                {/* 计时器 */}
                <RecordingTimer duration={duration} />

                {/* 倒计时 */}
                {maxDuration > 0 && (
                    <Text style={styles.remainingText}>
                        剩余 {Math.floor(remainingTime / 60)}:{remainingTime % 60 < 10 ? '0' : ''}{Math.floor(remainingTime % 60)}
                    </Text>
                )}
            </View>

            {/* 音频可视化 */}
            <AudioVisualization
                amplitude={amplitude}
                recording={recording && !paused}
                style={styles.visualization}
            />

            {/* 进度条 */}
            {maxDuration > 0 && (
                <View style={styles.progressContainer}>
                    <View
                        style={[
                            styles.progressBar,
                            { width: `${remainingPercent}%` }
                        ]}
                    />
                </View>
            )}

            {/* 控制按钮 */}
            <View style={styles.controls}>
                {initializing ? (
                    <ActivityIndicator size="small" color={theme.colors.primary.main} />
                ) : recording ? (
                    <>
                        {/* 录音中的控制按钮 */}
                        <TouchableOpacity
                            style={[styles.controlButton, styles.pauseButton]}
                            onPress={paused ? handleResume : handlePause}
                        >
                            <Text style={styles.controlButtonText}>
                                {paused ? '继续' : '暂停'}
                            </Text>
                        </TouchableOpacity>

                        <TouchableOpacity
                            style={[styles.controlButton, styles.stopButton]}
                            onPress={handleStop}
                        >
                            <Text style={styles.controlButtonText}>完成</Text>
                        </TouchableOpacity>
                    </>
                ) : (
                    /* 开始录音按钮 */
                    <TouchableOpacity
                        style={[styles.controlButton, styles.startButton]}
                        onPress={handleStart}
                    >
                        <Text style={styles.controlButtonText}>开始录音</Text>
                    </TouchableOpacity>
                )}
            </View>

            {/* 错误提示 */}
            {error && (
                <Text style={styles.errorText}>
                    错误: {error.message}
                </Text>
            )}
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        width: '100%',
        backgroundColor: theme.colors.background.paper,
        borderRadius: theme.borderRadius.md,
        padding: theme.spacing.md,
        ...Platform.select({
            ios: {
                shadowColor: theme.colors.common.black,
                shadowOffset: { width: 0, height: 1 },
                shadowOpacity: 0.1,
                shadowRadius: 2,
            },
            android: {
                elevation: 2,
            },
            web: {
                boxShadow: theme.shadows.sm,
            },
        }),
    },
    statusContainer: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        marginBottom: theme.spacing.sm,
    },
    statusIndicatorContainer: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    recordingIndicator: {
        width: 12,
        height: 12,
        borderRadius: 6,
        backgroundColor: theme.colors.error.main,
        marginRight: 8,
    },
    statusText: {
        fontSize: theme.typography.fontSize.sm,
        color: theme.colors.text.secondary,
    },
    timerText: {
        fontSize: theme.typography.fontSize.md,
        fontWeight: '500',
        color: theme.colors.text.primary,
    },
    remainingText: {
        fontSize: theme.typography.fontSize.xs,
        color: theme.colors.text.secondary,
    },
    visualization: {
        height: 60,
        marginVertical: theme.spacing.md,
    },
    visualizationContainer: {
        width: '100%',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        paddingHorizontal: theme.spacing.xs,
    },
    visualizationBar: {
        width: 4,
        borderRadius: 2,
        backgroundColor: theme.colors.primary.main,
    },
    progressContainer: {
        height: 4,
        backgroundColor: theme.colors.gray[200],
        borderRadius: 2,
        marginBottom: theme.spacing.md,
        overflow: 'hidden',
    },
    progressBar: {
        height: '100%',
        backgroundColor: theme.colors.primary.main,
    },
    controls: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
    },
    controlButton: {
        paddingVertical: theme.spacing.sm,
        paddingHorizontal: theme.spacing.lg,
        borderRadius: theme.borderRadius.md,
        minWidth: 100,
        justifyContent: 'center',
        alignItems: 'center',
        marginHorizontal: theme.spacing.xs,
    },
    startButton: {
        backgroundColor: theme.colors.primary.main,
    },
    pauseButton: {
        backgroundColor: theme.colors.warning.main,
    },
    stopButton: {
        backgroundColor: theme.colors.error.main,
    },
    controlButtonText: {
        color: theme.colors.common.white,
        fontSize: theme.typography.fontSize.md,
        fontWeight: '500',
    },
    errorText: {
        marginTop: theme.spacing.sm,
        color: theme.colors.error.main,
        fontSize: theme.typography.fontSize.sm,
        textAlign: 'center',
    },
});

export default AudioRecorder; 